iT邦幫忙

2024 iThome 鐵人賽

DAY 7
1
Modern Web

一些讓你看來很強的 ORM - prisma系列 第 7

Day07. 一些讓你看來很強的 ORM - prisma (schema)中

  • 分享至 

  • xImage
  •  

今天我們要來 demo primsaschema 的使用方式,大家還記得以下的 code 嗎?我們在 day 5 介紹 DB adapter 的時候有提到,怎麼讓 prisma 兼容其他 DB driver,還沒看過的讀者建議先去看 Day 5 的內容在看本篇會比較好喔~

import { Pool } from 'pg'
import { PrismaPg } from '@prisma/adapter-pg'
import { PrismaClient } from '@prisma/client'

const connectionString = `${process.env.DATABASE_URL}`

const pool = new Pool({ connectionString })
const adapter = new PrismaPg(pool)
const prisma = new PrismaClient({ adapter })
const main = async () => {
  const data = await prisma.users.findMany({})
  console.log(data)
}

然後筆者在文章中埋下一個伏筆是 prisma 其實支援 postgresqlschema 的功能,那經過昨天介紹 schema 用法後大家是不是有大概的概念了呢~接下來的篇幅將會說明在 prisma 中如何使用 schema

const adapter = new PrismaPg(pool, {
  schema: 'myPostgresSchema'
})

connect SQL URL

開始之前我們要先確定我們的 SQL URL 是可以連上的,大家可以先到 zeabur 起一個 postgresqlDB server~

> psql "postgresql://YOUR_URL/zeabur"

進去之後我們先查看 DBtable ,那因為筆者是採用有在使用的 DB 所以目前才會有以下的 table

>zeabur=# \dt;
              List of relations
 Schema |        Name        | Type  | Owner
--------+--------------------+-------+-------
 public | Authenticator      | table | root
 public | _prisma_migrations | table | root
 public | accounts           | table | root
 public | sessions           | table | root
 public | users              | table | root
 public | verificationtokens | table | root
(6 rows)

如果讀者沒有可以直接下 SQL 指令簡單的 create 一個 table

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    name VARCHAR(50),
);

之後我們回到專案把你的 SQL URL 放到 DB

// .env
DATABASE_URL="YOUR_URL"

DB Pull

大家應該還記得我們需要同步 DBprisma 所以要執行 pull 的動作

>npx prisma db pull  

pull 成功後他會跟你說已經同步到你的 prismaschema

>npx prisma db pull  
Prisma schema loaded from prisma/schema.prisma
Environment variables loaded from .env
Datasource "db": PostgreSQL database "zeabur", schema "public" at "sfo1.xxx.zeabur.com:31437"

✔ Introspected 5 models and wrote them into prisma/schema.prisma in 4.55s
      
Run prisma generate to generate Prisma Client.

此時你查看一下 schema.prisma 真的確實有剛剛 createtable~

// schema.prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model employees {
  id           String  @id
  name         String  
}

不過我們再仔細看一下剛剛 pulllog ,你會發現他會要你在執行一下 prisma generate ,原因是 db pull 不像執行 migration 一樣,會自動幫你 generate prisma client 需要的東西,包含 type 等等,所以每當你 pull 一次 DB 記得要再手動執行 generate

✔ Introspected 5 models and wrote them into prisma/schema.prisma in 4.55s
      
Run prisma generate to generate Prisma Client.

當你跑完 generate 並出現以下的 log 時候,這樣你的 DB pull 才算結束~

>npx prisma generate
Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma

✔ Generated Prisma Client (v5.19.1) to ./node_modules/@prisma/client in 69ms

Start by importing your Prisma Client (See: http://pris.ly/d/importing-client)

Tip: Need your database queries to be 1000x faster? Accelerate offers you that and more: https://pris.ly/tip-2-accelerate

Get Data

那因為我們目前的 table 是剛 create ,大家記得先去 prisma studio 先添加一筆資料,不然等下 data 會是空的

>npx prisma studio

https://ithelp.ithome.com.tw/upload/images/20240921/20145677YtbXUf5WNw.png

之後我們簡單 get 一下 data

>tsx watch index.ts 
//index.ts
const main = async () => {
  const data = await prisma.users.findMany({})
  console.log(data)
}
main()

現在我們終於拿到資料了~

[
  {
    id: '1',
    name: 'Danny',
    email: 'hiunji64@gmail.com',
    emailVerified: null,
    image: null,
    createdAt: 2024-09-15T05:40:48.404Z,
    updatedAt: 1970-01-01T00:00:00.000Z
  }
]

Switch DB Schema

大家應該還記得 schema 的概念很像是一個新的工作區,所有的 tabledata 都是獨立的,然後我們回到 SQL 去改一下我們的 schema 內容。

create schema

>zeabur=# CREATE SCHEMA test;
CREATE SCHEMA

成功 create

>zeabur=# \dn;
List of schemas
  Name  | Owner
--------+-------
 public | root
 test   | root
(2 rows)

SET schema

>zeabur=# SET SEARCH_PATH=test;
SET

查看當前的 schema ,這樣我們就成功在另外一個 schema 工作了~

>zeabur=# SELECT CURRENT_SCHEMA;
 current_schema
----------------
 test
(1 row)

因為是新的 schema 所以也不會有任何 table

>zeabur=# \dt;
Did not find any relations.

那一樣我們 create 一個新的 table 並查看有沒有成功

>zeabur=# CREATE TABLE test(
    id SERIAL PRIMARY KEY,
    name VARCHAR(50)
);
CREATE TABLE
>zeabur=# \dt;
       List of relations
 Schema | Name | Type  | Owner
--------+------+-------+-------
 test   | test | table | root
(1 row)

改好後我們的 connect URL 記得加上 schema 這個 queryDB URL

//.env
DATABASE_URL="postgresql://***.***/zeabur?schema=test"

並執行 DB pull

>npx prisma db pull 

你會發現我們的 schema 換成 test 這個 shcmea 有的 table 了,是不是很神奇~

// prisma.schema
model test {
  id   Int     @id @default(autoincrement())
  name String? @db.VarChar(50)
}

但這時你如果執行 generate 你會發現

>npx prisma generate

prisma 根本不知道你的 schema 有更動,prisma 還以為你在 public 這個 schema

>npx prisma generate
PrismaClientKnownRequestError: 
Invalid `prisma.test.findMany()` invocation:


The table `public.test` does not exist in the current database.

於是我們調整一下我們 adapterschema 這樣你才可以成功 generate prisma client

const adapter = new PrismaPg(pool, {
  schema: 'test'
})

generate 後你會發現,剛剛 get userscode 有問題了,原因是我們目前的 prisma client 已經是新的 schema 的內容,自然也不會有 publictable
https://ithelp.ithome.com.tw/upload/images/20240921/20145677xAoDcPdkKT.png

於是我們調整成新的 test table

const main = async () => {
  const data = await prisma.test.findMany({})
  console.log(data)
}

最後我們在執行一下 index.ts 如次我們就成功替換不同的 schema

 >tsx watch index.ts 
[]

總結

經過這幾天介紹 schema 的功能後相信大家對 shcmea 應該印象更加深刻了,筆者認為, schema 的使用情境會是當你有不同的 project 需要共同同一個 DB 時,不希望彼此的 table 或是 data 被污染到,才會需要用 schema ,使用上是蠻方便的,如果讀者喜歡的話或許可以用在自己的 project 上~好了今天內容先到這感謝大家耐心的閱讀,我們明天見~

大家如果有問題可以來小弟的群組討論~

✅ 前端社群 :
https://lihi3.cc/kBe0Y


上一篇
Day06. 一些讓你看來很強的 ORM - prisma (schema)上
下一篇
Day08. 一些讓你看來很強的 ORM - prisma (schema)下
系列文
一些讓你看來很強的 ORM - prisma30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言